use cpal::traits::{DeviceTrait, HostTrait, StreamTrait};
use std::fs::File;
use std::io::Write;
use std::sync::{Arc, Mutex};
use std::sync::atomic::{AtomicBool, Ordering};
use std::time::Duration;

use rubato::{FftFixedInOut, Resampler};

fn main() -> anyhow::Result<()> {
    let host = cpal::default_host();
    let device = host.default_input_device().expect("❌ 没有找到默认输入设备");

    let config = device.default_input_config().expect("❌ 无法获取输入配置");
    let sample_rate = config.sample_rate().0;
    let channels = config.channels() as usize;

    if config.sample_format() != cpal::SampleFormat::F32 {
        return Err(anyhow::anyhow!("当前程序仅支持 f32 格式输入"));
    }

    println!("🎤 输入设备: {}", device.name()?);
    println!("📐 输入格式: {:?}", config);

    let file = File::create("record_16k_mono.pcm")?;
    let writer = Arc::new(Mutex::new(file));

    let running = Arc::new(AtomicBool::new(true));
    {
        let running = running.clone();
        ctrlc::set_handler(move || {
            println!("\n🛑 收到退出信号，停止录音...");
            running.store(false, Ordering::SeqCst);
        })?;
    }

    let mut resampler = FftFixedInOut::<f32>::new(
		sample_rate as usize,
		16000,
		1024,
		1, // 只需要1个通道，输出是 mono
	)?;


    let writer_clone = writer.clone();

    let stream = device.build_input_stream(
        &config.into(),
        move |data: &[f32], _: &cpal::InputCallbackInfo| {
            let mut mono: Vec<f32> = vec![0.0; data.len() / channels];
            for (i, frame) in data.chunks(channels).enumerate() {
                mono[i] = frame.iter().sum::<f32>() / channels as f32;
            }

            if let Ok(resampled) = resampler.process(&[mono], None) {
                let pcm: Vec<i16> = resampled[0]
                    .iter()
                    .map(|f| (f * i16::MAX as f32).clamp(i16::MIN as f32, i16::MAX as f32) as i16)
                    .collect();

                let mut file = writer_clone.lock().unwrap();
                let bytes = bytemuck::cast_slice(&pcm);
                file.write_all(bytes).unwrap();
            }
        },
        err_fn,
        None,
    )?;

    stream.play()?;
    println!("🎙️ 正在录音并实时转换为 mono/16kHz/i16，按 Ctrl+C 停止...");

    while running.load(Ordering::SeqCst) {
        std::thread::sleep(Duration::from_millis(100));
    }

    println!("✅ 录音完成，文件已保存为 record_16k_mono.pcm");
    Ok(())
}

fn err_fn(err: cpal::StreamError) {
    eprintln!("❌ 音频流错误: {}", err);
}
